home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / Technical Documentation / develop / develop Issue 24 / develop Issue 24 code / Scriptable Database 1.0a15 / Foundation / AbstractIterator.cp < prev    next >
Encoding:
Text File  |  1996-02-19  |  16.9 KB  |  495 lines  |  [TEXT/CWIE]

  1.  
  2. #include "AbstractIterator.h"
  3. #include "AbstractScriptableObject.h"
  4. #include "AbstractCollector.h"
  5. #include "AbstractSearchSpec.h"
  6.  
  7. #include "Exceptions.h"
  8.  
  9. //
  10. // For TDeepIterator
  11. //
  12. #include "EntireContents.h"
  13.  
  14. //
  15. // For CopyMemory
  16. //
  17. #include "AbstractData.h"
  18.  
  19. //========================================================================================
  20. // CLASS TAbstractObjectIterator
  21. //========================================================================================
  22.  
  23. //----------------------------------------------------------------------------------------
  24. // TAbstractObjectIterator::~TAbstractObjectIterator
  25. //----------------------------------------------------------------------------------------
  26. TAbstractObjectIterator::~TAbstractObjectIterator()
  27.     {
  28.     }
  29.  
  30. //----------------------------------------------------------------------------------------
  31. // TAbstractObjectIterator::Dispose
  32. //----------------------------------------------------------------------------------------
  33. void TAbstractObjectIterator::Release()
  34.     {
  35.     delete this;
  36.     }
  37.  
  38. //----------------------------------------------------------------------------------------
  39. // TAbstractObjectIterator::RemoveCurrent
  40. //----------------------------------------------------------------------------------------
  41. void TAbstractObjectIterator::RemoveCurrent(const TAETransaction&)
  42.     {
  43.     FailErr(errAEEventNotHandled);
  44.     }
  45.  
  46. //----------------------------------------------------------------------------------------
  47. // TAbstractObjectIterator::CurrentDerivedFromOSLClass
  48. //
  49. // Override to avoid creating a designator just to compare the object class of
  50. // the current item.
  51. //----------------------------------------------------------------------------------------
  52. Boolean TAbstractObjectIterator::CurrentDerivedFromOSLClass(const TAETransaction& t, DescType objectClass)
  53.     {
  54.     TAbstractScriptableObject* current = this->Current(t);
  55.     Boolean isDerived = false;
  56.     
  57.     if(current != nil)
  58.         {
  59.         isDerived = current->DerivedFromOSLClass(t, objectClass);
  60.         current->DisposeDesignator();
  61.         }
  62.     
  63.     return isDerived;
  64.     } // TAbstractObjectIterator::CurrentDerivedFromOSLClass
  65.  
  66. //----------------------------------------------------------------------------------------
  67. // TAbstractObjectIterator::CountElements
  68. //----------------------------------------------------------------------------------------
  69. long TAbstractObjectIterator::CountElements(const TAETransaction& t, DescType desiredClass)
  70.     {
  71.     long count = 0;
  72.  
  73.     for(this->Reset(t); this->More(t); this->Next(t))
  74.         {
  75.         if(this->CurrentDerivedFromOSLClass(t, desiredClass))
  76.             {
  77.             ++count;
  78.             }
  79.         }
  80.     
  81.     return count;
  82.     }
  83.  
  84. //----------------------------------------------------------------------------------------
  85. // TAbstractObjectIterator::GetIndexedElement
  86. //----------------------------------------------------------------------------------------
  87. TAbstractScriptableObject* TAbstractObjectIterator::GetIndexedElement(const TAETransaction& t, DescType desiredClass, long index)
  88.     {
  89.     TAbstractScriptableObject* result = nil;
  90.  
  91.     for(this->Reset(t); this->More(t); this->Next(t))
  92.         {
  93.         if(this->CurrentDerivedFromOSLClass(t, desiredClass))
  94.             {
  95.             --index;
  96.             if(index == 0)
  97.                 {
  98.                 result = this->Current(t);
  99.                 break;
  100.                 }
  101.             }
  102.         }
  103.     
  104.     return result;
  105.     }
  106.  
  107. //----------------------------------------------------------------------------------------
  108. // TAbstractObjectIterator::GetNamedElement
  109. //
  110. // It is only necessary to override this method to improve the performance
  111. // of access by name
  112. //----------------------------------------------------------------------------------------
  113. TAbstractScriptableObject* TAbstractObjectIterator::GetNamedElement(const TAETransaction& t, DescType desiredClass, TDescriptor nameDesc)
  114.     {
  115.     TAbstractScriptableObject* result = nil;
  116.  
  117.     for(this->Reset(t); this->More(t); this->Next(t))
  118.         {
  119.         TAbstractScriptableObject* token = this->Current(t);
  120.         if(token->DerivedFromOSLClass(t, desiredClass))
  121.             {
  122.             Boolean match = token->CompareProperty(t, pName, kAEEquals, nameDesc);
  123.             if(match)
  124.                 {
  125.                 token->AddThisToMarkToken(result, kSingleItemOrUnion);
  126.                 token = nil;
  127.                 }
  128.             }
  129.         if(token != nil)
  130.             {
  131.             token->DisposeDesignator();
  132.             token = nil;
  133.             }
  134.         }
  135.     
  136.     return result;
  137.     } // TAbstractObjectIterator::GetNamedElement
  138.     
  139. //----------------------------------------------------------------------------------------
  140. // TAbstractObjectIterator::AccessBySearchSpec: 
  141. //----------------------------------------------------------------------------------------
  142. void TAbstractObjectIterator::AccessBySearchSpec(const TAETransaction& t, TAbstractCollector* collector, DescType desiredClass, TAbstractSearchSpec* searchSpec)
  143.     {
  144.     Boolean iterationDirection = collector->CollectorRequest(t, kSearchShouldIterateBackwards) ? kBackwardIteration : kForwardIteration;
  145.     for(this->Reset(t, iterationDirection); this->More(t) && (collector->CollectorRequest(t, kCollectionIsFull) == false); this->Next(t))
  146.         {
  147.         OSErr err = noErr;
  148.         
  149.         Try
  150.             {
  151.             TAbstractScriptableObject* token = this->Current(t);
  152.             if(token->DerivedFromOSLClass(t, desiredClass) && searchSpec->Compare(t, token))
  153.                 collector->AddToCollection(token);
  154.             else
  155.                 token->DisposeDesignator();
  156.             token = nil;
  157.             }
  158.         Catch(err)
  159.             {
  160.             }
  161.         }
  162.     } // TAbstractObjectIterator::AccessBySearchSpec
  163.  
  164. //----------------------------------------------------------------------------------------
  165. // TAbstractObjectIterator::SearchDeep
  166. //----------------------------------------------------------------------------------------
  167. void TAbstractObjectIterator::SearchDeep(const TAETransaction& t, TAbstractCollector* collector, DescType desiredClass, TAbstractSearchSpec* searchSpec)
  168.     {
  169.     TDeepIterator deepIter(nil);
  170.     
  171.     for(this->Reset(t); this->More(t); this->Next(t))
  172.         {
  173.         OSErr err = noErr;
  174.         
  175.         Try
  176.             {
  177.             TAbstractScriptableObject* elementToDeepSearch = this->Current(t);
  178.             deepIter.FocusOnNewRoot(elementToDeepSearch);
  179.                 
  180.             for(deepIter.Reset(t); deepIter.More(t); deepIter.Next(t))
  181.                 {
  182.                 Try
  183.                     {
  184.                     TAbstractScriptableObject* token = deepIter.Current(t);
  185.                     if(token->DerivedFromOSLClass(t, desiredClass) && searchSpec->Compare(t, token))
  186.                         collector->AddToCollection(token);
  187.                     else
  188.                         token->DisposeDesignator();
  189.                     token = nil;
  190.                     }
  191.                 Catch(err)
  192.                     {
  193.                     }
  194.                 }
  195.  
  196.             if(elementToDeepSearch->DerivedFromOSLClass(t, desiredClass) && searchSpec->Compare(t, elementToDeepSearch))
  197.                 collector->AddToCollection(elementToDeepSearch);
  198.             else
  199.                 elementToDeepSearch->DisposeDesignator();
  200.             }
  201.         Catch(err)
  202.             {
  203.             }
  204.         }
  205.     }
  206.  
  207. //----------------------------------------------------------------------------------------
  208. // TAbstractObjectIterator::RecursiveSearchDeep
  209. //----------------------------------------------------------------------------------------
  210. void TAbstractObjectIterator::RecursiveSearchDeep(const TAETransaction& t, TAbstractCollector* collector, DescType desiredClass, TAbstractSearchSpec* searchSpec)
  211.     {
  212.     for(this->Reset(t); this->More(t); this->Next(t))
  213.         {
  214.         OSErr err = noErr;
  215.         
  216.         Try
  217.             {
  218.             TAbstractScriptableObject* token = this->Current(t);
  219.             TAbstractObjectIterator* elementIter = token->ElementIterator(t);
  220.             elementIter->SearchDeep(t, collector, desiredClass, searchSpec);
  221.             if(token->DerivedFromOSLClass(t, desiredClass) && searchSpec->Compare(t, token))
  222.                 collector->AddToCollection(token);
  223.             else
  224.                 token->DisposeDesignator();
  225.             elementIter->Release();
  226.             elementIter = nil;
  227.             token = nil;
  228.             }
  229.         Catch(err)
  230.             {
  231.             }
  232.         }
  233.     }
  234.  
  235. //----------------------------------------------------------------------------------------
  236. // TAbstractObjectIterator::Contains
  237. //----------------------------------------------------------------------------------------
  238. Boolean TAbstractObjectIterator::Contains(const TAETransaction& t, TAbstractScriptableObject* objectToTestForMembership)
  239.     {
  240.     Boolean isContained = false;
  241.     
  242.     for(this->Reset(t); this->More(t) && (isContained == false); this->Next(t))
  243.         {
  244.         TAbstractScriptableObject* current = this->Current(t);
  245.         isContained = current->ObjectsAreTheSame(t, objectToTestForMembership);
  246.         current->DisposeDesignator();
  247.         }
  248.     
  249.     return isContained;
  250.     }
  251.  
  252. //========================================================================================
  253. // Class TSingleObjectIterator
  254. //========================================================================================
  255.  
  256. //----------------------------------------------------------------------------------------
  257. // TSingleObjectIterator::~TSingleObjectIterator
  258. //----------------------------------------------------------------------------------------
  259. TSingleObjectIterator::~TSingleObjectIterator()
  260.     {
  261.     } // TSingleObjectIterator::~TSingleObjectIterator
  262.     
  263. //----------------------------------------------------------------------------------------
  264. // TSingleObjectIterator::Reset
  265. //----------------------------------------------------------------------------------------
  266. void TSingleObjectIterator::Reset(const TAETransaction&, Boolean)
  267.     {
  268.     fCurrent = fObject;
  269.     } // TSingleObjectIterator::Reset
  270.     
  271. //----------------------------------------------------------------------------------------
  272. // TSingleObjectIterator::More
  273. //----------------------------------------------------------------------------------------
  274. Boolean TSingleObjectIterator::More(const TAETransaction&) const
  275.     {
  276.     return (fCurrent != nil);
  277.     } // TSingleObjectIterator::More
  278.     
  279. //----------------------------------------------------------------------------------------
  280. // TSingleObjectIterator::Next
  281. //----------------------------------------------------------------------------------------
  282. void TSingleObjectIterator::Next(const TAETransaction&)
  283.     {
  284.     fCurrent = nil;
  285.     } // TSingleObjectIterator::Next
  286.     
  287. //----------------------------------------------------------------------------------------
  288. // TSingleObjectIterator::Current
  289. //----------------------------------------------------------------------------------------
  290. TAbstractScriptableObject* TSingleObjectIterator::Current(const TAETransaction&)
  291.     {
  292.     return fCurrent->CloneDesignator();
  293.     } // TSingleObjectIterator::Current
  294.     
  295. //----------------------------------------------------------------------------------------
  296. // TSingleObjectIterator::CountElements
  297. //
  298. // We know that this iterator will only represent one object at the most
  299. //----------------------------------------------------------------------------------------
  300. long TSingleObjectIterator::CountElements(const TAETransaction& t, DescType desiredClass)
  301.     {
  302.     return fObject == nil ? 0 : fObject->DerivedFromOSLClass(t, desiredClass);
  303.     } // TSingleObjectIterator::CountElements
  304.     
  305. //----------------------------------------------------------------------------------------
  306. // TSingleObjectIterator::GetIndexedElement
  307. //----------------------------------------------------------------------------------------
  308. TAbstractScriptableObject* TSingleObjectIterator::GetIndexedElement(const TAETransaction& t, DescType desiredClass, long index)
  309.     {
  310.     TAbstractScriptableObject* result = nil;
  311.     
  312.     if(index == 1)
  313.         result = fObject;
  314.     if((result == nil) || (result->DerivedFromOSLClass(t, desiredClass) == false))
  315.         FailErr(errAEIndexTooLarge);
  316.     
  317.     return result->CloneDesignator();
  318.     } // TSingleObjectIterator::GetIndexedElement
  319.  
  320.  
  321. //========================================================================================
  322. // CLASS TCollectionIterator
  323. //========================================================================================
  324.  
  325. //----------------------------------------------------------------------------------------
  326. // TCollectionIterator::~TCollectionIterator
  327. //----------------------------------------------------------------------------------------
  328. TCollectionIterator::~TCollectionIterator()
  329.     {
  330.     for(long i=0; i<fItersInCollection; ++i)
  331.         {
  332.         fIterCollection[i]->Release();
  333.         }
  334.     if(fIterCollection != nil)
  335.         delete [] fIterCollection;
  336.     }
  337.  
  338. //----------------------------------------------------------------------------------------
  339. // TCollectionIterator::AddIterator
  340. //----------------------------------------------------------------------------------------
  341. void TCollectionIterator::AddIterator(TAbstractObjectIterator* iter)
  342.     {
  343.     if(fItersInCollection >= fCollectionSize)
  344.         {
  345.         long newCollectionSize = fCollectionSize << 1;
  346.         if(newCollectionSize == 0)
  347.             newCollectionSize = 8;
  348.  
  349.         TAbstractObjectIterator** newIterCollection = new TAbstractObjectIterator*[newCollectionSize];
  350.         if(fIterCollection != nil)
  351.             {
  352.             CopyMemory(fIterCollection, newIterCollection, fCollectionSize * sizeof(Ptr)); // memcpy(newIterCollection, fIterCollection, fCollectionSize * sizeof(Ptr));
  353.             delete [] fIterCollection;
  354.             }
  355.         fIterCollection = newIterCollection;
  356.         fCollectionSize = newCollectionSize;
  357.         }
  358.     
  359.     fIterCollection[fItersInCollection] = iter;
  360.     ++fItersInCollection;
  361.     }
  362.  
  363. //----------------------------------------------------------------------------------------
  364. // TCollectionIterator::AddObject
  365. //----------------------------------------------------------------------------------------
  366. void TCollectionIterator::AddObject(const TAETransaction& t, TAbstractScriptableObject* object)
  367.     {
  368.     TAbstractObjectIterator* iter = object->DirectObjectIterator(t);
  369.     if(iter != nil)
  370.         this->AddIterator(iter);
  371.     }
  372.  
  373. //----------------------------------------------------------------------------------------
  374. // TCollectionIterator::AddElementsOfObject
  375. //----------------------------------------------------------------------------------------
  376. void TCollectionIterator::AddElementsOfObject(const TAETransaction& t, TAbstractScriptableObject* object)
  377.     {
  378.     TAbstractObjectIterator* iter = object->ElementIterator(t);
  379.     if(iter != nil)
  380.         this->AddIterator(iter);
  381.     }
  382.  
  383. //----------------------------------------------------------------------------------------
  384. // TCollectionIterator::CurrentIterator
  385. //----------------------------------------------------------------------------------------
  386. TAbstractObjectIterator* TCollectionIterator::CurrentIterator() const
  387.     {
  388.     TAbstractObjectIterator* iter = nil;
  389.     
  390.     if((fCurrentIter >= 0) && (fCurrentIter < fItersInCollection))
  391.         iter = fIterCollection[fCurrentIter];
  392.     
  393.     return iter;
  394.     }
  395.  
  396. //----------------------------------------------------------------------------------------
  397. // TCollectionIterator::Reset
  398. //----------------------------------------------------------------------------------------
  399. void TCollectionIterator::Reset(const TAETransaction& t, Boolean iterationDirection /*= kForwardIteration*/)
  400.     {
  401.     fDirection = iterationDirection;
  402.     
  403.     if(fDirection == kForwardIteration)
  404.         {
  405.         fCurrentIter = 0;
  406.         }
  407.     else
  408.         {
  409.         fCurrentIter = fItersInCollection - 1;
  410.         }
  411.     TAbstractObjectIterator* iter = this->CurrentIterator();
  412.     if(iter)
  413.         {
  414.         iter->Reset(t, fDirection);
  415.         while(iter && (iter->More(t) == false))
  416.             {
  417.             if(fDirection == kForwardIteration)
  418.                 ++fCurrentIter;
  419.             else
  420.                 --fCurrentIter;
  421.             iter = this->CurrentIterator();    
  422.             }
  423.         }
  424.     }
  425.  
  426. //----------------------------------------------------------------------------------------
  427. // TCollectionIterator::More
  428. //----------------------------------------------------------------------------------------
  429. Boolean TCollectionIterator::More(const TAETransaction& t) const
  430.     {
  431.     //
  432.     // If there is a current iterator, it's More() method
  433.     // should always return true.  But we check anyway.
  434.     //
  435.     TAbstractObjectIterator* iter = this->CurrentIterator();
  436.     if(iter)
  437.         return iter->More(t);
  438.     else
  439.         return false;
  440.     }
  441.  
  442. //----------------------------------------------------------------------------------------
  443. // TCollectionIterator::Next
  444. //----------------------------------------------------------------------------------------
  445. void TCollectionIterator::Next(const TAETransaction& t)
  446.     {
  447.     TAbstractObjectIterator* iter = this->CurrentIterator();
  448.     if(iter)
  449.         {
  450.         iter->Next(t);
  451.         while(iter && (iter->More(t) == false))
  452.             {
  453.             if(fDirection == kForwardIteration)
  454.                 ++fCurrentIter;
  455.             else
  456.                 --fCurrentIter;
  457.             iter = this->CurrentIterator();
  458.             if(iter != nil)
  459.                 iter->Reset(t, fDirection);
  460.             }
  461.         }
  462.     }
  463.  
  464. //----------------------------------------------------------------------------------------
  465. // TCollectionIterator::Current
  466. //----------------------------------------------------------------------------------------
  467. TAbstractScriptableObject* TCollectionIterator::Current(const TAETransaction& t)
  468.     {
  469.     TAbstractObjectIterator* iter = this->CurrentIterator();
  470.     if(iter)
  471.         return iter->Current(t);
  472.     else
  473.         return nil;
  474.     }
  475.  
  476. //----------------------------------------------------------------------------------------
  477. // TCollectionIterator::CurrentDerivedFromOSLClass
  478. //----------------------------------------------------------------------------------------
  479. Boolean TCollectionIterator::CurrentDerivedFromOSLClass(const TAETransaction& t, DescType objectClass)
  480.     {
  481.     TAbstractObjectIterator* iter = this->CurrentIterator();
  482.     if(iter)
  483.         return iter->CurrentDerivedFromOSLClass(t, objectClass);
  484.     else
  485.         return false;
  486.     }
  487.  
  488. //----------------------------------------------------------------------------------------
  489. // TCollectionIterator::SearchDeep
  490. //----------------------------------------------------------------------------------------
  491. void TCollectionIterator::SearchDeep(const TAETransaction& t, TAbstractCollector* collector, DescType desiredClass, TAbstractSearchSpec* searchSpec)
  492.     {
  493.     this->RecursiveSearchDeep(t, collector, desiredClass, searchSpec);
  494.     }
  495.